package com.css.fxfzdzzh.modules.basicData.service.impl;

import cn.hutool.core.util.PageUtil;
import com.css.fxfzdzzh.base.annotation.EntityValue;
import com.css.fxfzdzzh.base.exception.ShpFieldException;
import com.css.fxfzdzzh.base.response.RestResponse;
import com.css.fxfzdzzh.constants.GeomTypeEnum;
import com.css.fxfzdzzh.constants.YNEnum;
import com.css.fxfzdzzh.modules.basicData.entity.LandForm;
import com.css.fxfzdzzh.modules.basicData.entity.NaturalDensity;
import com.css.fxfzdzzh.modules.basicData.entity.SensingImage;
import com.css.fxfzdzzh.modules.basicData.landslideSite.entity.FieldDesc;
import com.css.fxfzdzzh.modules.basicData.landslideSite.entity.LandslideSiteFileData;
import com.css.fxfzdzzh.modules.basicData.landslideSite.vo.TableVo;
import com.css.fxfzdzzh.modules.basicData.repository.impl.SensingImageRepository;
import com.css.fxfzdzzh.modules.basicData.vo.ListVo;
import com.css.fxfzdzzh.modules.basicData.vo.QueryByVersionParam;
import com.css.fxfzdzzh.modules.eqLandslide.lawAnalysis.vo.SlopesVO;
import com.css.fxfzdzzh.util.CreateGson;
import com.css.fxfzdzzh.util.PlatformDateUtils;
import com.css.fxfzdzzh.util.PlatformObjectUtils;
import com.css.fxfzdzzh.util.UUIDGenerator;
import com.css.fxfzdzzh.util.fileParsing.ParsingResult;
import com.css.fxfzdzzh.util.fileParsing.shp.ShpAnalyticUtil;
import com.css.fxfzdzzh.web.PlatformSessionContext;
import com.css.fxfzdzzh.zcpt.sys.entity.SUser;
import com.css.fxfzdzzh.zcpt.sys.service.SUserService;
import lombok.extern.java.Log;
import lombok.extern.log4j.Log4j;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author Dbj
 * @date 2023年02月28日  17:10
 * 遥感映像
 */
@Slf4j
@Service
public class SensingImageService {

    @Resource
    private SensingImageRepository sensingImageRepository;

    @Resource
    private LandformService landformService;

    @Resource
    private SUserService sUserService;

    public void updateByLsVersion(String tempVersionCode, String versionCode, Integer dataRangeCountry) {
        sensingImageRepository.updateByVersion(tempVersionCode,versionCode,dataRangeCountry);
    }

    public void deleteByVersion(String versionCode) {
        sensingImageRepository.deleteByVersion(versionCode);
    }

    public void updateLs(String versionCode, String tempVersionCode) {
        sensingImageRepository.updateLs(versionCode,tempVersionCode);
    }

    public RestResponse saveShpTemporaryData(ParsingResult shpData) {
        //生成临时版本号
        try {
            String dataVersion = UUID.randomUUID().toString().replaceAll("-", "");
            List<SensingImage> list = this.getList(shpData.getShpList(), dataVersion);
            if (list.size()>0){
                sensingImageRepository.byShpBatchSave(list);
            }
            ListVo listVo = new ListVo("0", null, dataVersion, "滑坡遥感影响", null, list);
            return RestResponse.succeed(listVo);
        } catch (ShpFieldException e) {
            log.error(e.getMessage() + "\n错误数据 > {}", shpData.getShpList());
            return RestResponse.fail(e.getMessage());
        } catch (IndexOutOfBoundsException e1) {
            return RestResponse.fail("字段数量不符合要求");
        }
    }

    private List<SensingImage> getList(List<List<Object>> shpList, String dataVersion) throws ShpFieldException{
        String userID = PlatformSessionContext.getUserID(); // 获取当前登录用户
        String user = sUserService.getSUser(userID);
        SUser sUser = CreateGson.createGson().fromJson(user, SUser.class);
        ArrayList<SensingImage> arrayList = new ArrayList<>();
        for (int i = 0; i < shpList.size(); i++) {
            List<Object> list = shpList.get(i);
            SensingImage obj = new SensingImage();
            //临时版本号
            obj.setVersionCode(dataVersion);
            //当前用户
            obj.setCreateUser(userID);
            obj.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
            obj.setCreateUserName(sUser.getUserName());
            obj.setDelFlag(YNEnum.Y.toString());
            obj.setUploadTime(new Date());
            obj.setDssiId(UUIDGenerator.getUUID());
            //obj.setGeom(ShpAnalyticUtil.checkGeomTypeOf(list.get(0).toString(), GeomTypeEnum.MULTIPOLYGON));
            obj.setGeom("POINT("+list.get(11).toString()+" " +list.get(12).toString()+")");
            obj.setName(ShpAnalyticUtil.getStringVal(list.get(1).toString(), "名称", true));
            obj.setOutdoorNum(ShpAnalyticUtil.getStringVal(list.get(2).toString(), "野外编号", true));
            obj.setLandslideTime(ShpAnalyticUtil.getStringVal(list.get(3).toString(), "滑坡年代", true));
            obj.setLandslideYear(PlatformObjectUtils.isNotEmpty(list.get(4))?ShpAnalyticUtil.getStringVal(list.get(4).toString(), "滑坡时间年", false):"");
            obj.setLandslideMonth(PlatformObjectUtils.isNotEmpty(list.get(5))?ShpAnalyticUtil.getStringVal(list.get(5).toString(), "滑坡时间月", false):"");
            obj.setLandslideDay(PlatformObjectUtils.isNotEmpty(list.get(6))?ShpAnalyticUtil.getStringVal(list.get(6).toString(), "滑坡时间日", false):"");
            obj.setLandslideType(ShpAnalyticUtil.getStringVal(list.get(7).toString(), "滑坡类型", true));
            obj.setLandslideShape(ShpAnalyticUtil.getStringVal(list.get(8).toString(), "滑坡性质", true));
            obj.setCrown(PlatformObjectUtils.isNotEmpty(list.get(9))?ShpAnalyticUtil.getStringVal(list.get(9).toString(), "冠", false):"");
            obj.setToe(PlatformObjectUtils.isNotEmpty(list.get(10))?ShpAnalyticUtil.getStringVal(list.get(10).toString(), "趾", false):"");
            obj.setLongitude(BigDecimal.valueOf(ShpAnalyticUtil.getDoubleVal(list.get(11).toString(), "经度", true)));
            obj.setLatitude(BigDecimal.valueOf(ShpAnalyticUtil.getDoubleVal(list.get(12).toString(), "纬度", true)));
            obj.setProvince(ShpAnalyticUtil.getStringVal(list.get(13).toString(), "省", true));
            obj.setCity(ShpAnalyticUtil.getStringVal(list.get(14).toString(), "市", true));
            obj.setCountry(ShpAnalyticUtil.getStringVal(list.get(15).toString(), "区（县）", true));
            obj.setTown(ShpAnalyticUtil.getStringVal(list.get(16).toString(), "乡", true));
            obj.setVillage(ShpAnalyticUtil.getStringVal(list.get(17).toString(), "村", true));
            obj.setUnderAge(ShpAnalyticUtil.getStringVal(list.get(18).toString(), "地层时代", true));
            obj.setFormationLithology(ShpAnalyticUtil.getStringVal(list.get(19).toString(), "地层岩性", true));
            obj.setStructuralPosition(PlatformObjectUtils.isNotEmpty(list.get(20))?ShpAnalyticUtil.getStringVal(list.get(20).toString(), "构造部位", false):"");
            obj.setEarthquakeIntensity(PlatformObjectUtils.isNotEmpty(list.get(21))?ShpAnalyticUtil.getStringVal(list.get(21).toString(), "地震烈度", false):"");
            obj.setStratigraphicDip(PlatformObjectUtils.isNotEmpty(list.get(22))?ShpAnalyticUtil.getStringVal(list.get(22).toString(), "地层倾向", false):"");
            obj.setStratigraphicAngle(PlatformObjectUtils.isNotEmpty(list.get(23))?ShpAnalyticUtil.getStringVal(list.get(23).toString(), "地层倾角", false):"");
            obj.setMicrorelief(PlatformObjectUtils.isNotEmpty(list.get(24))?ShpAnalyticUtil.getStringVal(list.get(24).toString(), "微地貌", false):"");
            obj.setRelativeRiverPosition(PlatformObjectUtils.isNotEmpty(list.get(25))?ShpAnalyticUtil.getStringVal(list.get(25).toString(), "相对河流位置", false):"");
            obj.setSlopeStructureType(PlatformObjectUtils.isNotEmpty(list.get(26))?ShpAnalyticUtil.getStringVal(list.get(26).toString(), "斜坡结构类型", false):"");
            obj.setControlStructureType(PlatformObjectUtils.isNotEmpty(list.get(27))?ShpAnalyticUtil.getStringVal(list.get(27).toString(), "控滑结构面类型", false):"");
            obj.setControlStructureInclination(PlatformObjectUtils.isNotEmpty(list.get(28))?ShpAnalyticUtil.getStringVal(list.get(28).toString(), "控滑结构面倾向", false):"");
            obj.setControlStructureAngle(PlatformObjectUtils.isNotEmpty(list.get(29))?ShpAnalyticUtil.getStringVal(list.get(29).toString(), "控滑结构面倾角", false):"");
            obj.setLandslideLength(BigDecimal.valueOf(ShpAnalyticUtil.getDoubleVal(list.get(30).toString(), "滑坡长度", true)));
            obj.setLandslideWidth(BigDecimal.valueOf(ShpAnalyticUtil.getDoubleVal(list.get(31).toString(), "滑坡宽度", true)));
            obj.setLandslideThickness(BigDecimal.valueOf(ShpAnalyticUtil.getDoubleVal(list.get(32).toString(), "滑坡厚度", true)));
            obj.setLandslideSlope(BigDecimal.valueOf(ShpAnalyticUtil.getDoubleVal(list.get(33).toString(), "滑坡坡度", true)));
            obj.setLandslideAspect(ShpAnalyticUtil.getStringVal(list.get(34).toString(), "滑坡坡向", true));
            obj.setLandslideArea(BigDecimal.valueOf(ShpAnalyticUtil.getDoubleVal(list.get(35).toString(), "滑坡面积", true)));
            obj.setLandslideVolume(BigDecimal.valueOf(ShpAnalyticUtil.getDoubleVal(list.get(36).toString(),"滑坡体积", true)));
            obj.setLandslidePlaneShape(ShpAnalyticUtil.getStringVal(list.get(37).toString(), "滑坡平面形态", true));
            obj.setLandslideProfileShape(PlatformObjectUtils.isNotEmpty(list.get(38))?ShpAnalyticUtil.getStringVal(list.get(38).toString(), "滑坡剖面形态", false):"");
            obj.setScaleGrade(ShpAnalyticUtil.getStringVal(list.get(39).toString(), "规模等级", true));
            arrayList.add(obj);
        }
        return arrayList;
    }

    public List<SlopesVO> getSlopeAreaByGeomAndVersion1(String geomText, String param3){
        return sensingImageRepository.getSlopeAreaByGeomAndVersion1(geomText,param3);
    }
    public List<Map<String, Object>> getByGeomAndVersion2(String tableName, String param2) {
        return sensingImageRepository.getByGeomAndVersion2(tableName,param2);
    }

    public RestResponse getYwData(QueryByVersionParam queryByVersionParam) {
        List<SensingImage> list = sensingImageRepository.getYwData(queryByVersionParam);
        if (queryByVersionParam.getPage() != null && queryByVersionParam.getRows() != null) {
            Long total = sensingImageRepository.countByDataVersion(queryByVersionParam);
            return RestResponse.succeed(new HashMap<String, Object>() {{
                put("title", getFieldTable());
                put("data", list);
                put("total", total);
                put("page", queryByVersionParam.getPage());
                put("rows", queryByVersionParam.getRows());
                put("totalPage", PageUtil.totalPage(total, queryByVersionParam.getRows()));
            }});
        } else {
            return RestResponse.succeed(new HashMap<String, Object>() {{
                put("title", getFieldTable());
                put("data", list);
            }});
        }
    }
    public List<TableVo> getFieldTable(){
        Field[] declaredFields = SensingImage.class.getDeclaredFields();
        List<TableVo> list = new ArrayList<>();
        if(declaredFields.length>0){
            for(Field field : declaredFields){
                FieldDesc fieldDesc = new FieldDesc();
                field.setAccessible(true);
                EntityValue entityValue = field.getAnnotation(EntityValue.class);
                if(entityValue==null){
                    continue;
                }
                TableVo vo = new TableVo();
                vo.setLabel(entityValue.name());
                vo.setProp(field.getName());
                list.add(vo);
            }
        }
        return list;
    }
    public List<FieldDesc>  getFieldDesc() {
        Field[] declaredFields = SensingImage.class.getDeclaredFields();
        List<FieldDesc> list = new ArrayList<>();
        AtomicInteger sno = new AtomicInteger(1);
        if(declaredFields.length>0){
            for(Field field : declaredFields){
                FieldDesc fieldDesc = new FieldDesc();
                field.setAccessible(true);
                EntityValue entityValue = field.getAnnotation(EntityValue.class);
                if(entityValue==null){
                    continue;
                }
                String type = entityValue.type();
                String must = entityValue.must();
                String name = entityValue.name();
                String desc = entityValue.desc();
                fieldDesc.setType(type).setMust(must).setName(name).setDesc(desc).setSno(sno.get());
                sno.getAndAdd(1);
                list.add(fieldDesc);
            }
        }
        return list;
    }

    public Integer getValidDataNum(String versionCode) {
        return sensingImageRepository.getValidDataNum(versionCode);
    }

    public SensingImage getYwDetails(String id) {
        return sensingImageRepository.getYwDetails(id);
    }
}
